package com.ellecity06.common.helper


import android.annotation.SuppressLint
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import com.ellecity06.common.utils.logD
import kotlin.math.abs
import kotlin.math.log10
import kotlin.math.max
import kotlin.math.min

/**
 * @author ellecity06
 * @time 2025/3/14 16:12
 * @des 声音采集
 */
class VoiceRecorder(
    private val onDecibelUpdate: (Double) -> Unit
) {
    private var audioRecord: AudioRecord? = null
    private var isRecording = false
    private var bufferSize = 0

    // 新增累积缓冲区相关参数
    private val sampleRate = 44100
    private val targetSamples = (sampleRate * 0.5).toInt()  // 500ms的样本数
    private var accumulatedSamples = ShortArray(targetSamples * 2)  // 双倍缓冲防止溢出
    private var currentIndex = 0

    @SuppressLint("MissingPermission")
    fun startRecording() {
        bufferSize = AudioRecord.getMinBufferSize(
            sampleRate,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT
        )

        audioRecord = AudioRecord(
            MediaRecorder.AudioSource.MIC,
            sampleRate,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            bufferSize
        )

        audioRecord?.startRecording()
        isRecording = true

        Thread {
            val buffer = ShortArray(bufferSize / 2)

            while (isRecording) {
                val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0
                if (bytesRead > 0) {
                    synchronized(this) {
                        // 将数据拷贝到累积缓冲区
                        if (currentIndex + bytesRead > accumulatedSamples.size) {
                            // 处理缓冲区溢出（实际使用中应适当扩大缓冲区）
                            currentIndex = 0
                        }

                        System.arraycopy(
                            buffer, 0,
                            accumulatedSamples, currentIndex,
                            bytesRead
                        )
                        currentIndex += bytesRead

                        // 处理完整的时间窗口
                        while (currentIndex >= targetSamples) {
                            val window = accumulatedSamples.copyOfRange(0, targetSamples)
                            val amplitude = calculateAmplitude(window)
                            val decibel = calculateDecibel(amplitude)
//                            val mapToDynamicRange = mapToDynamicRange(decibel)
//                            logD("当前分贝: ${decibel} dB--转换之后的分贝：${mapToDynamicRange} dB")
                            onDecibelUpdate(decibel)

                            // 移动剩余数据到缓冲区头部
                            val remaining = currentIndex - targetSamples
                            System.arraycopy(
                                accumulatedSamples, targetSamples,
                                accumulatedSamples, 0,
                                remaining
                            )
                            currentIndex = remaining
                        }
                    }
                }
            }
        }.start()
    }

    fun stopRecording() {
        isRecording = false
        audioRecord?.stop()
        audioRecord?.release()
        audioRecord = null
    }

    private fun calculateAmplitude(buffer: ShortArray): Double {
        var maxAmplitude = 0
        for (value in buffer) {
            val absValue = abs(value.toInt())
            if (absValue > maxAmplitude) {
                maxAmplitude = absValue
            }
        }
        return maxAmplitude.toDouble()
    }
    private var dynamicMinDb = -100.0 // 初始最小值
    private var dynamicMaxDb = 0.0 // 初始最大值

    private fun mapToDynamicRange(decibel: Double): Int {
        // 更新动态范围（可选：添加衰减逻辑避免长期漂移）
        dynamicMinDb = min(dynamicMinDb, decibel)
        dynamicMaxDb = max(dynamicMaxDb, decibel)

        // 防止除以零（初始状态处理）
        if (dynamicMaxDb - dynamicMinDb < 1e-5) {
            return 50 // 默认中间值
        }

        // 动态映射
        return ((decibel - dynamicMinDb) / (dynamicMaxDb - dynamicMinDb) * 100).toInt()
    }
    private fun calculateDecibel(amplitude: Double): Double {
        // 16位PCM最大值为32767（2^15 - 1）
        val referenceAmplitude = 32767.0
        return 20 * log10(amplitude / referenceAmplitude)
    }
}